iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0
Software Development

From State Machine to XState系列 第 23

Day23 - 在 XState 中的平行式狀態 Parallel States

  • 分享至 

  • xImage
  •  

還記得我們在 Day 13 的例子嗎?

有個 Input 的 UI 元件,且它有以下 [Invalid / Valid]、[Disabled / Enabled]、[Changed / Unchanged],這 3 類型的特點

https://ithelp.ithome.com.tw/upload/images/20210927/20130721esiomcqiFn.png
我們假設

  • 有沒有 Invalid 不影響會不會 Disabled;
  • 有沒有 Invalid 不影響會不會 Changed;
  • 有沒有 Disabled 不影響會不會 Changed...
    並且假如我們說這 3 類特徵任意搭配組合也都是合理的...

今天就即將在 XState 實作,寫出 machineConfig 來!
你說 XState 的 config 如何描述 Parallel State 呢?

1. 如何在 XState 描述 Parallel States

以下是一個 一般的 FSM

 {
    id: "myId",
    initial: "state1",
    states: {
      state1: {
        on: {
          event1: { target: "state2" }
        }
      },
      state2: {
        on: {
          event2: { target: "state1" }
        }
      }
    }
  }

我們只要在 states 前面加上一組 [key / value] -> type: 'parallel', ,並在上面原本 state1state2 之間,原本直接寫下 [on + event1], [on + event2] 改成另外一組新的子狀態機定義

TLDR 視覺化互動狀態機

  id: "myId",
+ type: "parallel",
- initial: "state1",
  states: {
    state1: {
+     initial: "state1-1",
+     states: {
+       "state1-1": {
+         on: {
+           "event1-1": { target: "state1-2" },
+         },
+       },
+       "state1-2": {
+         on: {
+           "event1-2": { target: "state1-1" },
+         },
+       },
+     },
    },
    state2: {
+     initial: "state2-1",
+     states: {
+       "state2-1": {
+         on: {
+           "event2-1": { target: "state2-2" },
+         },
+       },
+       "state2-2": {
+         on: {
+           "event2-2": { target: "state2-1" },
+         },
+       },
+     },
    },
  },
});

https://ithelp.ithome.com.tw/upload/images/20211008/20130721pWQS67KCiB.png

如此就可以完成一個簡易的平行狀態機


題外話,XState 官方也有提供視覺化工具 Visualizer ,讓你可以簡易的撰寫完 machineConfig 後,就能直接看到 State Chart 並且能與之互動

剛剛的範例可參考視覺化互動狀態機

另外我們現在會看 Visualizer 上使用到舊版 API Machine,其實 XState 目前也已經有新版的 Visualizer 了,只不過我還不太熟悉如何分享,所以在這邊先用舊版的分享

舊版 https://xstate.js.org/viz
新版 https://stately.ai/viz

除了新版的 Visualizer,官方也提供了 DX 更好的 tool, inspect 套件,也希望能在這次鐵人賽有機會能介紹到


2. 完成需求


const inputMachine = createMachine({

  id: "inputMachine_v1",
  type: "parallel",

  states: {
    valid: {
      initial: "valid",
      states: {
        invalid: {
          on: {
            VALIDATE: { target: "valid" },
          },
        },
        valid: {
          on: {
            INVALIDATE: { target: "invalid" },
          },
        },
      },
    },
    enabled: {
      initial: "enabled",
      states: {
        disabled: {
          on: {
            ENABLE: { target: "enabled" },
          },
        },
        enabled: {
          on: {
            DISABLE: { target: "disabled" },
          },
        },
      },
    },
    changed: {
      initial: "unchanged",
      states: {
        unchanged: {
          on: {
            CHANGE: { target: "changed" },
          },
        },
        changed: {
          on: {
            REVERT_CHANGE: { target: "unchanged" },
          },
        },
      },
    },
  },
});

Demo Visualizer

https://ithelp.ithome.com.tw/upload/images/20211008/201307211J6UpoVUtY.png

如此我們便完成了 Day 13 的例子。

參考資料

https://xstate.js.org/docs/guides/parallel.html


上一篇
Day22 - 在 XState, 狀態機器裡無窮盡的狀態、 資料:Extended State and context and assign API - 2
下一篇
Day24 - 在 XState 中的階層式狀態 Hierarchical States
系列文
From State Machine to XState31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
TD
iT邦新手 4 級 ‧ 2021-10-11 22:39:38

能夠直接視覺化好有趣啊~ 不過也就代表 state machine 相當的有規範

Ken Chen iT邦新手 4 級 ‧ 2021-10-12 00:59:47 檢舉

沒錯~超酷的/images/emoticon/emoticon37.gif

我要留言

立即登入留言